﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;

namespace DNA.Mvc.jQuery
{
    public class DatePickerBuilder : jQueryComponentBuilder<DatePickerOptions, DatePicker, DatePickerBuilder>
    {
        public DatePickerBuilder(DatePicker datePicker, ViewContext context, IViewDataContainer container) : base(datePicker, context, container) { }

        protected override string jQueryPluginName
        {
            get { return "datepicker"; }
        }


        //public DatePickerBuilder MultipleMonths(int months)
        //{
        //    Options(opts => {
        //        opts.NumberOfMonths = months;
        //    });
        //    return this;
        //}

        public DatePickerBuilder Value(DateTime date)
        {
            Options(opts => {
                opts.Value = date;
            });
            return this;
        }

        public DatePickerBuilder DateFormat(string format)
        {
            return this;
        }

        public void RenderCalendar()
        {
            Options(opts => { opts.DisplayMode = DatePickerDisplayModes.Calendar; });
            Component.DisplayMode = DatePickerDisplayModes.Calendar;
            this.Render();
        }

        private static string ISO8601Format(string format)
        {
            string formatted = format;
            //Format year
            if (formatted.IndexOf("yy") > -1)
                formatted = formatted.Replace("yy", "y");

            //if (formatted.IndexOf("yy") > -1)
            //    formatted = formatted.Replace("yy", "y");

            if (formatted.IndexOf("MMMM") > -1)
                formatted = formatted.Replace("MMMM", "MM");
            else
            {
                if (formatted.IndexOf("MMM") > -1)
                    formatted = formatted.Replace("MMM", "M");
                else
                {
                    if (formatted.IndexOf("MM") > -1)
                        formatted = formatted.Replace("MM", "mm");
                    else
                        if (formatted.IndexOf("M") > -1)
                            formatted = formatted.Replace("M", "m");
                }
            }

            if (formatted.IndexOf("dddd") > -1)
                formatted = formatted.Replace("dddd", "DD");

            if (formatted.IndexOf("ddd") > -1)
                formatted = formatted.Replace("ddd", "D");

            return formatted;
        }

        public override void Render()
        {
            RenderComponent();
            _InitScripts();
        }

        public override MvcHtmlString GetHtml()
        {
            _InitScripts();
            return MvcHtmlString.Create(Component.GetHtml());
        }

        private void _InitScripts()
        {
            if (options == null)
            {
                options = new DatePickerOptions();
                options.AnimationOnShow = "blind";
            }

            string format = "MM-dd-yyyy";
            if (!string.IsNullOrEmpty(options.DateFormatString))
                format = options.DateFormatString;
            else
                if (!string.IsNullOrEmpty(options.DefaultDateString))
                    format = options.DefaultDateString;
            string name = Component.Name;

            var opts = new jQueryScriptBuilder("#" + name, "datepicker");


            var initScripts = new StringBuilder();
            var html = MvcHtmlString.Empty;


            if (options.DisplayMode == DatePickerDisplayModes.Calendar)
            {
                StringBuilder selectScripts = new StringBuilder();
                selectScripts.Append("$('#")
                                        .Append(name)
                                        .Append("').children('input') .val($('#")
                                        .Append(name)
                                        .Append("').datepicker('getDate'));");
                options.OnSelect += selectScripts.ToString();
                if (options.Value.HasValue)
                    initScripts.Append("$('#")
                      .Append(name)
                      .Append("').datepicker('setDate','")
                      .Append(options.Value.Value.ToString(format))
                      .Append("');");
            }

            opts.AddOptions(options);


            if (!string.IsNullOrEmpty(options.ButtonImageUrl))
                opts.AddOption("buttonImage", options.ButtonImageUrl, true);

            if ((options.DayNames != null) && (options.DayNames.Length > 0))
                opts.AddOption("dayNames", options.DayNames);

            if ((options.MinDayNames != null) && (options.MinDayNames.Length > 0))
                opts.AddOption("dayNamesMin", options.MinDayNames);

            if ((options.ShortDayNames != null) && (options.ShortDayNames.Length > 0))
                opts.AddOption("dayNamesShort", options.ShortDayNames);

            if ((options.MonthNames != null) && (options.MonthNames.Length > 0))
                opts.AddOption("monthNames", options.MonthNames);

            if ((options.MonthShortNames != null) && (options.MonthShortNames.Length > 0))
                opts.AddOption("monthNamesShort", options.MonthShortNames);

            //if (!string.IsNullOrEmpty(options.DateFormatString))
            opts.AddOption("dateFormat", ISO8601Format(format), true);

            if (!string.IsNullOrEmpty(options.AnotherFormatString))
                opts.AddOption("altFormat", ISO8601Format(options.AnotherFormatString), true);

            if (options.MaxDateValue.HasValue)
                opts.AddOption("maxDate", options.MaxDateValue.Value.ToString(format), true);

            if (options.MinDateValue.HasValue)
                opts.AddOption("minDate", options.MinDateValue.Value.ToString(format), true);

            if (!string.IsNullOrEmpty(options.LocID))
            {
                initScripts.Append("$.datepicker.setDefaults($.datepicker.regional['")
                                  .Append(options.LocID)
                                  .Append("']);");
                Helper.RegisterStartupScript(initScripts.ToString());
            }


            Helper.RegisterStartupScript(opts.ToString());
            if (options.DisplayMode == DatePickerDisplayModes.Picker)
                Helper.RegisterStartupScript("$('#" + name + "').parent().children('.d-datepicker-button').click(function(){$('#" + name + "').focus(); });");

            if (options.Value.HasValue)
            {
                string dateStr = options.Value.Value.ToString(format);
                Helper.RegisterStartupScript("$(\"#" + name + "\").datepicker('setDate','" + dateStr + "');");
            }
        }
    }
}
